home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / wield.c < prev    next >
C/C++ Source or Header  |  1993-01-24  |  8KB  |  283 lines

  1. /*    SCCS Id: @(#)wield.c    3.1    92/12/10    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6.  
  7. /* elven weapons vibrate warningly when enchanted beyond a limit */
  8. #define is_elven_weapon(optr)    ((optr)->otyp == ELVEN_ARROW\
  9.                 || (optr)->otyp == ELVEN_SPEAR\
  10.                 || (optr)->otyp == ELVEN_DAGGER\
  11.                 || (optr)->otyp == ELVEN_SHORT_SWORD\
  12.                 || (optr)->otyp == ELVEN_BROADSWORD\
  13.                 || (optr)->otyp == ELVEN_BOW)
  14.  
  15. /* Note: setuwep() with a null obj, and uwepgone(), are NOT the same!  Sometimes
  16.  * unwielding a weapon can kill you, and lifesaving will then put it back into
  17.  * your hand.  If lifesaving is permitted to do this, use
  18.  * setwuep((struct obj *)0); otherwise use uwepgone().
  19.  */
  20. void
  21. setuwep(obj)
  22. register struct obj *obj;
  23. {
  24.     setworn(obj, W_WEP);
  25.     /* Note: Explicitly wielding a pick-axe will not give a "bashing"
  26.      * message.  Wielding one via 'a'pplying it will.
  27.      */
  28.     if (obj)
  29.         unweapon = ((obj->otyp >= BOW || obj->otyp <= BOOMERANG) &&
  30.             obj->otyp != PICK_AXE && obj->otyp != UNICORN_HORN);
  31.     else
  32.         unweapon = TRUE;    /* for "bare hands" message */
  33. }
  34.  
  35. void
  36. uwepgone()
  37. {
  38.     if (uwep) {
  39.         setnotworn(uwep);
  40.         unweapon = TRUE;
  41.     }
  42. }
  43.  
  44. static const char NEARDATA wield_objs[] =
  45.     { ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0 };
  46.  
  47. int
  48. dowield()
  49. {
  50.     register struct obj *wep;
  51.     register int res = 0;
  52.  
  53.     multi = 0;
  54. #ifdef POLYSELF
  55.     if (cantwield(uasmon)) {
  56.         pline("Don't be ridiculous!");
  57.         return(0);
  58.     }
  59. #endif
  60.     if (!(wep = getobj(wield_objs, "wield"))) /* nothing */;
  61.     else if (uwep == wep)
  62.         You("are already wielding that!");
  63.     else if (welded(uwep))
  64.         weldmsg(uwep, TRUE);
  65.     else if (wep == &zeroobj) {
  66.         if (uwep == 0)
  67.         You("are already empty %s.", body_part(HANDED));
  68.         else  {
  69.           You("are empty %s.", body_part(HANDED));
  70.           setuwep((struct obj *) 0);
  71.           res++;
  72.         }
  73.     } else if (!uarmg &&
  74. #ifdef POLYSELF
  75.            !resists_ston(uasmon) &&
  76. #endif
  77.            (wep->otyp == CORPSE && wep->corpsenm == PM_COCKATRICE)) {
  78.         /* Prevent wielding cockatrice when not wearing gloves --KAA */
  79.         You("wield the cockatrice corpse in your bare %s.",
  80.             makeplural(body_part(HAND)));
  81. # ifdef POLYSELF
  82.         if (!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  83. # endif
  84.         {
  85.         You("turn to stone...");
  86.         killer_format = KILLED_BY;
  87.         killer="touching a cockatrice corpse";
  88.         done(STONING);
  89.         }
  90.     } else if (uarms && bimanual(wep))
  91.         You("cannot wield a two-handed %s while wearing a shield.",
  92.         is_sword(wep) ? "sword" :
  93.             wep->otyp == BATTLE_AXE ? "axe" : "weapon");
  94.     else if (wep->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))
  95.         You("cannot wield that!");
  96.     else if (!wep->oartifact || touch_artifact(wep,&youmonst)) {
  97.         res++;
  98.         if (wep->cursed &&
  99.             (wep->oclass == WEAPON_CLASS ||
  100.              wep->otyp == HEAVY_IRON_BALL || wep->otyp == PICK_AXE ||
  101.              wep->otyp == UNICORN_HORN || wep->otyp == TIN_OPENER)) {
  102.             const char *tmp = xname(wep), *thestr = "The ";
  103.             if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4))
  104.             tmp = thestr;
  105.             else tmp = "";
  106.             pline("%s%s %s to your %s!",
  107.             tmp, aobjnam(wep, "weld"),
  108.             (wep->quan == 1L) ? "itself" : "themselves", /* a3 */
  109.             body_part(HAND));
  110.             wep->bknown = TRUE;
  111.         } else {
  112.             /* The message must be printed before setuwep (since
  113.              * you might die and be revived from changing weapons),
  114.              * and the message must be before the death message and
  115.              * Lifesaved rewielding.  Yet we want the message to
  116.              * say "weapon in hand", thus this kludge.
  117.              */
  118.             long dummy = wep->owornmask;
  119.             wep->owornmask |= W_WEP;
  120.             prinv(NULL, wep, 0L);
  121.             wep->owornmask = dummy;
  122.         }
  123.         setuwep(wep);
  124.     }
  125.     return(res);
  126. }
  127.  
  128. void
  129. erode_weapon(acid_dmg)
  130. boolean acid_dmg;
  131. /* Rust weapon, or corrode it if acid damage is called for */
  132. {
  133.     if(!uwep || uwep->oclass != WEAPON_CLASS) return;    /* %% */
  134.     if (uwep->greased) {
  135.         grease_protect(uwep,NULL,FALSE);
  136.     } else if(uwep->oerodeproof ||
  137.        (acid_dmg ? !is_corrodeable(uwep) : !is_rustprone(uwep))) {
  138.         if (flags.verbose || !(uwep->oerodeproof && uwep->rknown))
  139.             Your("%s not affected.", aobjnam(uwep, "are"));
  140.         if (uwep->oerodeproof) uwep->rknown = TRUE;
  141.     } else if (uwep->oeroded < MAX_ERODE) {
  142.         Your("%s%s!", aobjnam(uwep, acid_dmg ? "corrode" : "rust"),
  143.              uwep->oeroded+1 == MAX_ERODE ? " completely" :
  144.              uwep->oeroded ? " further" : "");
  145.         uwep->oeroded++;
  146.     } else
  147.         if (flags.verbose)
  148.             Your("%s completely %s.",
  149.              aobjnam(uwep, Blind ? "feel" : "look"),
  150.              acid_dmg ? "corroded" : "rusty");
  151. }
  152.  
  153. int
  154. chwepon(otmp, amount)
  155. register struct obj *otmp;
  156. register int amount;
  157. {
  158.     register const char *color = Hallucination ? hcolor() :
  159.                      (amount < 0) ? Black : blue;
  160.     register const char *xtime;
  161.  
  162.     if(!uwep || (uwep->oclass != WEAPON_CLASS && uwep->otyp != PICK_AXE
  163.             && uwep->otyp != UNICORN_HORN)) {
  164.         char buf[36];
  165.  
  166.         Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
  167.             (amount >= 0) ? "twitch" : "itch");
  168.         strange_feeling(otmp, buf);
  169.         exercise(A_DEX, amount >= 0);
  170.         return(0);
  171.     }
  172.  
  173.     if(uwep->otyp == WORM_TOOTH && amount >= 0) {
  174.         uwep->otyp = CRYSKNIFE;
  175.         Your("weapon seems sharper now.");
  176.         uwep->cursed = 0;
  177.         return(1);
  178.     }
  179.  
  180.     if(uwep->otyp == CRYSKNIFE && amount < 0) {
  181.         uwep->otyp = WORM_TOOTH;
  182.         Your("weapon seems duller now.");
  183.         return(1);
  184.     }
  185.  
  186.     if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) {
  187.         if (!Blind)
  188.         Your("%s %s.", aobjnam(uwep, "faintly glow"), color);
  189.         return(1);
  190.     }
  191.     /* there is a (soft) upper and lower limit to uwep->spe */
  192.     if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
  193.                                 && rn2(3)) {
  194.         if (!Blind)
  195.         Your("%s %s for a while and then evaporate%s.",
  196.          aobjnam(uwep, "violently glow"), color,
  197.          uwep->quan == 1L ? "s" : "");
  198.         else
  199.         Your("%s.", aobjnam(uwep, "evaporate"));
  200.  
  201.         while(uwep)        /* let all of them disappear */
  202.                 /* note: uwep->quan = 1 is nogood if unpaid */
  203.         useup(uwep);
  204.         return(1);
  205.     }
  206.     if (!Blind) {
  207.         xtime = (amount*amount == 1) ? "moment" : "while";
  208.         Your("%s %s for a %s.",
  209.          aobjnam(uwep, amount == 0 ? "violently glow" : "glow"),
  210.          color, xtime);
  211.     }
  212.     uwep->spe += amount;
  213.     if(amount > 0) uwep->cursed = 0;
  214.  
  215.     /*
  216.      * Enchantment, which normally improves a weapon, has an
  217.      * addition adverse reaction on Magicbane whose effects are
  218.      * spe dependent.  Give an obscure clue here.
  219.      */
  220.     if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) {
  221.         Your("right %s %sches!",
  222.             body_part(HAND),
  223.             (((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
  224.     }
  225.  
  226.     /* an elven magic clue, cookie@keebler */
  227.     if ((uwep->spe > 5)
  228.         && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
  229.         Your("%s unexpectedly.",
  230.         aobjnam(uwep, "suddenly vibrate"));
  231.  
  232.     return(1);
  233. }
  234.  
  235. int
  236. welded(obj)
  237. register struct obj *obj;
  238. {
  239.     if (obj && obj == uwep && obj->cursed &&
  240.           (obj->oclass == WEAPON_CLASS ||
  241.            obj->otyp == HEAVY_IRON_BALL ||
  242.            obj->otyp == TIN_OPENER || obj->otyp == PICK_AXE ||
  243.            obj->otyp == UNICORN_HORN))
  244.     {
  245.         obj->bknown = TRUE;
  246.         return 1;
  247.     }
  248.     return 0;
  249. }
  250.  
  251. /* The reason for "specific" is historical; some parts of the code used
  252.  * the object name and others just used "weapon"/"sword".  This function
  253.  * replaced all of those.  Which one we use is really arbitrary.
  254.  */
  255. void
  256. weldmsg(obj, specific)
  257. register struct obj *obj;
  258. boolean specific;
  259. {
  260.     char buf[BUFSZ];
  261.  
  262.     if (specific) {
  263.         long savewornmask = obj->owornmask;
  264.         obj->owornmask &= ~W_WEP;
  265.         Strcpy(buf, Doname2(obj));
  266.         obj->owornmask = savewornmask;
  267.     } else
  268.         Sprintf(buf, "Your %s%s",
  269.             is_sword(obj) ? "sword" : "weapon",
  270.             plur(obj->quan));
  271.     Strcat(buf, (obj->quan == 1L) ? " is" : " are");
  272. #ifdef POLYSELF
  273.     Sprintf(eos(buf), " welded to your %s!",
  274.         bimanual(obj) ? (const char *)makeplural(body_part(HAND)) : body_part(HAND));
  275. #else
  276.     Sprintf(eos(buf), " welded to your hand%s!",
  277.         bimanual(obj) ? "s" : "");
  278. #endif
  279.     pline(buf);
  280. }
  281.  
  282. /*wield.c*/
  283.